package com.knowledge.review.designPatterns.behavioralpattern.strategypattern;

import lombok.AllArgsConstructor;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

// 支付方式抽象类
public abstract class Payment {
    public String pay(String uid, double money) {
        double balance = queryBalance(uid);
        if (balance < money) {
            return "支付失败!余额不足!欠" + (money - balance) + "元!";
        }
        return "支付成功!支付金额:" + money + "余额剩余:" + (balance - money);
    }
    protected abstract String getPaymentName();
    protected abstract double queryBalance(String uid);
}
// 现金支付 默认方式
class Cash extends Payment{
    @Override
    protected String getPaymentName() {
        return "现金支付";
    }
    @Override
    protected double queryBalance(String uid) {
        return 1000;
    }
}
// 支付宝类
class AliPay extends Payment {
 
    @Override
    protected String getPaymentName() {
        return "支付宝";
    }
 
    @Override
    protected double queryBalance(String uid) {
        return 500;
    }
}
// 微信支付类
class WeChatPay extends Payment {
    @Override
    protected String getPaymentName() {
        return "微信支付";
    }
 
    @Override
    protected double queryBalance(String uid) {
        return 300;
    }
}
// 支付方式容器策略类
class PaymentStrategy {
    private static Map<String, Payment> map = new ConcurrentHashMap<>();
    static {
        map.put("WeChat", new WeChatPay());
        map.put("Ali", new AliPay());
    }
    public static Payment getPayment(String payment) {
        return map.get(payment) == null ? new Cash() : map.get(payment);
    }
 
}
// 订单交易类
@AllArgsConstructor
class Order {
    private String uid;
    private double amount;
    public String pay() {
        return pay("cash");
    }
    public String pay(String key) {
        Payment payment = PaymentStrategy.getPayment(key);
        System.out.println("欢迎使用" + payment.getPaymentName());
        System.out.println("本次交易金额:" + this.amount + ",开始扣款...");
        return payment.pay(this.uid, this.amount);
    }
}

class Test1{
    // 测试方法
    public static void main(String[] args) {
        Order order = new Order("20221014001", 500);
        //欢迎使用微信支付
        //本次交易金额:500.0,开始扣款...
        //支付失败!余额不足!欠200.0元!
        System.out.println(order.pay("WeChat"));
        //欢迎使用支付宝
        //本次交易金额:500.0,开始扣款...
        //支付成功!支付金额:500.0余额剩余:0.0
        System.out.println(order.pay("Ali"));
        //欢迎使用现金支付
        //本次交易金额:500.0,开始扣款...
        //支付成功!支付金额:500.0余额剩余:500.0
        System.out.println(order.pay());
    }
}